package com.example.sentinel_demo.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.sentinel_demo.pojo.User;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description TODO
 * @Author JFeng
 * @Date 2024/5/10
 */

public class SentinelHandler {

    /**
     * 必须为public 且 static，参数和源接口方法一致，最后一个参数可以是BlockException
     * 可以根据BlockException区分不同异常的流控规则
     *
     * @param name
     * @param blockException
     * @return User
     */
    public static User sentinelHandler(String name, BlockException blockException) {
        blockException.printStackTrace();
        return User.builder().msg("被流控").name(name).build();
    }

    public static User sentinelHandlerDegrade(String name, BlockException blockException) {
        blockException.printStackTrace();
        return User.builder().msg("被降级").name(name).build();
    }

    /**
     * 需要是static，参数需要和源接口方法参数一致
     *
     * @param name
     * @param e
     * @return
     */
    public static User fallbackHandler(String name, Throwable e) {
        e.printStackTrace();
        return User.builder().msg("方法中出现了异常").name(name).build();
    }

    /**
     * 测试泛型擦除
     */
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        Method method = arr.getClass().getDeclaredMethod("add", Object.class);
        method.invoke(arr, "测试泛型擦除");
        System.out.println(arr + ":" + arr.getClass());
        for (Object obj : arr) {
            System.out.println(obj.getClass());
        }

        List<Integer> integerList = new ArrayList<>();
        List<String> stringList = new ArrayList<>();
        // 结果是true,都是class java.util.ArrayList,所以List<E>为参数时不能用于区分重载
        System.out.println();
        System.out.println(integerList.getClass());
        System.out.println(integerList.getClass() == stringList.getClass());


        People<String> people = new People<>();
        System.out.println(people.getClass());
        Field[] declaredFields = people.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field.getName() + ":" + field.getType());
        }
//        System.out.println(people instanceof People<String>);
    }

    static class People<E> {
        /**
         * 会编译成：
         * static class People {
         * private Object obj;
         * private String name;
         * }
         */
        private E obj;
        private String name;
    }
}
